Ext.define('UX.codeview.ButtonX', {
	extend : 'Ext.button.Button',
	alias : 'widget.codeviewbuttonx',
	requires : [ 'codeview.Popup' ],
	componentCls : 'ux-codeviewx',
	overCls : 'over',
	pressedCls : 'pressed',
	iconCls : 'ux-codeviewx-icon',
	border : 1,

	disabledEnter : false,
	// default > component, cell editor > editor
	fieldType : 'component',

	pStore : null,
	cdvType : 'gcm',
	remoteFilter : true,
	params : {},
	factoryConditionEnabled : true,
	serviceUrl : '',
	servicePath : '',
	table : '',
	// ex) {column : "columnName", ascending : true or false}
	order : [],
	// ex) {column : "columnName" , value : value or function, scope: this,
	// operator : "like"}
	condition : [],
	pageSize : window.CODEVIEW_PAGESIZE || 1000,
	showFailureMsg : true,

	pColumns : [ {
		text : 'Name',
		dataIndex : 'key1',
		disabledSearch : false,
		// fieldId : '',
		flex : 1
	}, {
		text : 'Description',
		dataIndex : 'data1',
		disabledSearch : false,
		flex : 2
	} ],
	defaultPopupConfig : {},
	fieldSearch : false,

	multiSelect : false,
	multiSelectCount : 100,
	delimiter : ',',

	constructor : function(configs) {
		var config = Ext.clone(configs||{});
		// type
		var cdvType = config.type || config.cdvType;
		if (cdvType) {
			config.cdvType = config.type.toLowerCase();
			delete config.type;
		}
		else {
			config.cdvType = 'gcm';
		}

		// service
		if (Ext.isObject(config.service)) {
			config.serviceUrl = config.service.name;
			config.servicePath = config.service.path || '';
			config.cdvType = 'service';
			delete config.service;
		}

		// pop-up Columns
		if (config.columns) {
			this.isGcmTableColumn = true;
			config.pColumns = config.columns;
			Ext.Array.each(config.pColumns, function(col) {
				if (Ext.isEmpty(col.width) && Ext.isEmpty(col.flex)) {
					col.flex = 1;
				}
			});
			delete config.columns;
		}

		// pop-up title
		if (!config.title && config.fieldLabel) {
			config.title = config.fieldLabel;
		}

		// handler
		delete config.handler;

		this.callParent([ config ]);
	},

	initComponent : function() {
		this.callParent();

		this.addEvents('beforestoreload', 'afterstoreload', 'select', 'showpopup', 'closepopup', 'clearfieldvalue', 'setfieldvalue');

		this.pStore = this.createStore();
		if (this.pStore) {
			this.pStore.mon(this.pStore, {
				load : function(store, records, success) {
					this.fireEvent('afterstoreload', this, store, records, success);
					if (this.codeviewPopup) {
						this.codeviewPopup.fireEvent('afterstoreload', this, store, records, success);
					}
				},
				scope : this
			});
		}

		var event = {
			setfieldvalue : function(me, records) {
				this.setFieldValue(records);
			},
			clearfieldvalue : function(me) {
				this.clearFieldValue();
			},
			afterrender : function() {
				this.bindEvents();
			},
			scope : this
		};
		this.mon(this, event);
	},

	setFieldValue : function(records) {
		Ext.Array.each(this.pColumns, function(col) {
			var field = this.getBindField(col);
			if (field) {
				if (this.multiSelect === true) {
					var data = [];
					Ext.Array.each(records, function(record) {
						data.push(record.get(col.dataIndex));
					}, this);

					var value = data.join(this.delimiter);
					if (value == this.delimiter) {
						value = '';
					}

					field.setValue(value);
				} else {
					field.setValue(records.get(col.dataIndex));

				}
			}
		}, this);
		
		this.fireEvent('select', this, records);
	},

	clearFieldValue : function() {
		var fields = this.getBindFields();
		Ext.Array.each(fields, function(field) {
			field.setValue('');
		});
	},

	handler : function(btn) {
		var params = Ext.clone(this.params);
		if (this.fireEvent('beforestoreload', this, this.pStore, params) === false) {
			return false;
		}

		if(this.cdvType === 'gcm' && this.table && !this.isGcmTableColumn){
			Ext.Ajax.request({
				url : 'service/basViewTable.json',
				params : {
					procstep : '1',
					tableName : this.table
				},
				success : function(response, opts) {
					var result = response.responseObj;
					var gcmColumns = [];

					for (var i = 1; i <= 10; i++) {
						var dataIndex = 'key'+i;
						var text = result[dataIndex + 'Prt'];
						if(text){
							gcmColumns.push({
								text : text,
								dataIndex : dataIndex,
								disabledSearch : false,
								disabledEnter : false,
								flex : 1
							});
						}
					}
					for (i = 1; i <= 10; i++) {
						var dataIndex = 'data'+i;
						var text = result[dataIndex + 'Prt'];
						if(text){
							gcmColumns.push({
								text : text,
								dataIndex : dataIndex,
								disabledSearch : false,
								disabledEnter : false,
								flex : 1
							});
						}
					}
					this.isGcmTableColumn = true;
					this.pColumns = gcmColumns;
					this.showPopup(params);
				},
				scope : this
			});
		}
		else{
			this.showPopup(params);
		}
	},

	showPopup : function(params) {
		var config = Ext.clone(this.defaultPopupConfig);
		var columns = Ext.clone(this.pColumns);
		var fieldValues = {};

		// field
		Ext.Array.each(columns, function(col, index) {
			var field = this.getBindField(col);
			if (field) {
				if (this.multiSelect === false && this.fieldSearch === true) {
					col.searchValue = field.getValue();
				}

				if (this.multiSelect === true) {
					var fv = Ext.isEmpty(field.getValue()) ? [] : field.getValue().split(this.delimiter);
					fieldValues[col.dataIndex] = fv;
				}
			}
		}, this);

		Ext.apply(config, {
			codeviewField : this,
			title : this.title,
			pStore : this.pStore,
			pColumns : columns,
			pParams : params,
			pCdvType : this.cdvType,
			pCondition : Ext.clone(this.condition),
			pPageSize : this.pageSize,
			pShowFailureMsg : this.showFailureMsg
		});

		if (this.multiSelect === false) {
			this.codeviewPopup = Ext.create('codeview.SingleCodeviwePopup', config).show();
		} else {
			var selectedValues = [];
			var keys = Ext.Object.getKeys(fieldValues);
			var colCnt = 0;

			Ext.Array.each(keys, function(key) {
				var fvalue = fieldValues[key];
				if (colCnt < fvalue.length) {
					colCnt = fvalue.length;
				}
			}, this);

			for (var i = 0; i < colCnt; i++) {
				var sv = {};
				Ext.Array.each(keys, function(key) {
					sv[key] = fieldValues[key][i];
				});
				selectedValues.push(sv);
			}

			config.pMultiSelectCount = this.multiSelectCount;
			config.pDelimiter = this.delimiter;
			config.pSelectedValues = selectedValues;
			this.codeviewPopup = Ext.create('codeview.MultiCodeviewPopup', config).show();
		}
	},

	bindEvents : function() {
		var fields = this.getBindFields();
		if (this.disabledEnter === true) {
			return;
		}

		Ext.Array.each(fields, function(field) {
			if (field.disabledEnter === true) {
				return;
			}

			field.mon(field, {
				specialkey : function(f, e) {
					if (e.getKey() == e.ENTER) {
						this.handler(this);
					}
				},
				scope : this
			});
		}, this);
	},

	getBindFields : function() {
		var columns = Ext.clone(this.pColumns) || [];
		var fields = [];
		Ext.Array.each(columns, function(col) {
			//if (!col.hidden && !Ext.isEmpty(col.fieldId)) {
			if (!Ext.isEmpty(col.fieldId)) {
				var field = this.getBindField(col);
				if (field) {
					fields.push(field);
				}
			}
		}, this);

		return fields;
	},

	getBindField : function(column) {
		if (Ext.isEmpty(column.fieldId)) {
			return false;
		}
		var selector = '#' + column.fieldId;
		function find(child){
			var scope = child.up();
			if(!scope){
				return false;
			}
			var self_function = arguments.callee;
			var field = scope.down(selector);
			if(!field){
				return self_function(scope);
			}
			else {
				if (column.disabledEnter === true) {
					field.disabledEnter = true;
				}
				return field;
			}
		}
		
		return find(this); 
	},

	bindStore : function(store) {
		var oldStore = this.pStore;

		if (oldStore != store) {
			oldStore.destroyStore();

			this.pStore = store;

			this.pStore.mon(this.pStore, {
				load : function(store, records, success) {
					this.fireEvent('afterstoreload', this, store, records, success);
				},
				scope : this
			});
		}
	},

	// store
	createStore : function() {
		var params = {};
		var serviceUrl = '';
		var servicePath = '';
		var fields = this.createFields();

		if (this.cdvType == 'memory') {
			return Ext.create('Ext.data.Store', {
				fields : fields
			});
		} else if (this.cdvType == 'gcm' || this.cdvType == 'table') {
			params = {
				procstep : '1',
				select : fields,
				table : this.table,
				type : this.cdvType
			};
			serviceUrl = 'service/basViewCodeList.json';
			servicePath = 'list';
		} else if (this.cdvType == 'service') {
			serviceUrl = this.serviceUrl;
			servicePath = this.servicePath;
		}

		return Ext.create('Ext.data.Store', {
			autoLoad : false,
			fields : fields,
			remoteFilter : this.remoteFilter,
			pageSize : this.pageSize,
			proxy : {
				type : 'payload',
				api : {
					read : serviceUrl
				},
				extraParams : params,
				actionMethods : {
					read : 'POST'
				},
				reader : {
					type : 'json',
					root : servicePath,
					totalProperty : 'total'
				}
			}
		});
	},

	createFields : function() {
		var fields = [];
		var columns = this.pColumns || [];
		var conditions = this.condition || [];

		Ext.Array.each(columns, function(col) {
			if (col.dataIndex) {
				fields.push(col.dataIndex);
			}
		});

		Ext.Array.each(conditions, function(cond) {
			if (cond.column) {
				if (Ext.Array.contains(fields, cond.column) === false) {
					fields.push(cond.column);
				}
			}
		});

		return fields;
	}
});